package com.topnav.mc.involve.http;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.FutureRequestExecutionService;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;

/**
 * @Author: kenny
 * @Date: 2023/12/23 9:52
 *  HttpClient 不支持带下划线的 HOST URL
 */
@Slf4j
public class HttpClientUtil {
    //private static CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom().build();

    /**
     * 异步 httpclient
     * @param url
     * @param timeout 超时设备 毫秒
     * @Param SetHearders 设置hearder
     * @param okCallback
     * @param errCallBack
     */
    public static void get(String url, int timeout,SetHearders setHearders,FutureCallback okCallback, ErrorEvent errCallBack){
        // 2.创建异步httpclient对象
        //CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom().build();
        CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
        try {
            //url = url.replace("_","\_");
            log.info(">>>>>>>>>url: {}",url);
            // 3.0启动
            httpclient.start();
            // 3.1请求参数 url Illegal character in query
            HttpGet httpget = new HttpGet(url);
            if (setHearders != null){
                setHearders.setHearder(httpget);
            }
            httpget.setConfig(createConfig(timeout));
            // 3.2发起请求，不阻塞，马上返回
            httpclient.execute(httpget, okCallback);
            // 3.3休眠20s,避免请求执行完成前，关闭了链接
            Thread.sleep(20000);
        }catch (Exception e){
            log.error(e.toString());
            if (errCallBack != null){
                errCallBack.run(e.toString());
            }
        }finally {
            if (httpclient != null){
                try{
                    httpclient.close();
                }catch (IOException e1){
                    e1.printStackTrace();
                }
            }
        }

    }

    /**
     * 同步get方法
     * @param url
     * @param timeout  超时设备 毫秒
     * @Param SetHearders 设置hearder
     * @param okCallBack 成功回调
     * @param errorCallBack 错误回调
     * @param timeoutCaback  超时回调
     */
    public static void get(String url,int timeout, SetHearders setHearders,OkEvent okCallBack,
                           ErrorEvent errorCallBack, TimeoutEvent timeoutCaback){
        // 1. 创建HttpClient实例
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 2. 创建GET请求方法实例
        HttpGet httpGet = new HttpGet(url);
        if (setHearders != null){
            setHearders.setHearder(httpGet);
        }
        CloseableHttpResponse response = null;
        httpGet.setConfig(createConfig(timeout));
        try {
            // 3. 调用HttpClient实例来执行GET请求方法，得到response
            response = httpClient.execute(httpGet);
            // 4. 读response，判断是否访问成功 2xx表示 成功。
            int status = response.getStatusLine().getStatusCode();
            if (status == 200) {
                // 对得到后的实例可以进行处理，例如读取回复体，读取html
                HttpEntity entity = response.getEntity();
                String res = EntityUtils.toString(entity);
                System.out.println("远程调用--->" + res);
                if (okCallBack!=null){
                    okCallBack.run(res);
                }
            } else {
                if (errorCallBack != null){
                    errorCallBack.run("Unexpected response status: " + status);
                }
                //throw new ClientProtocolException("Unexpected response status: " + status);
            }
        }catch (Exception e) {
            log.error(e.toString());
            if (errorCallBack != null){
                errorCallBack.run(e.toString());
            }
        }finally {
            try{
                // 6. 释放连接
                if (response != null){response.close();}
                if (httpClient != null){httpClient.close();};
            }catch (IOException e1){
                log.error(e1.toString());
            }
        }
		/*
			if (pairs != null){
				String paramStr = pairs.toString();
				UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(pairs.getPairs(), "utf-8");
				httpGet.setParams(pairs);
				httpGet.setHeader("Content-Type", "application/x-www-form-urlencoded");
				httpGet.setEntity(urlEncodedFormEntity);
			}else{
				//UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(pairs.getPairs(), "utf-8");
				//httpPost.setEntity(urlEncodedFormEntity);
				//httpPost.setEntity(urlEncodedFormEntity);
				httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
			}
		}catch (Exception e){

		}*/
        //执行 post请求
        /*CloseableHttpResponse response = closeableHttpClient.execute(httpPost);*/
    }

    /**
     * 创建配置参数，超时设置等
     * @param millSec 毫秒
     * @return
     */
    public static RequestConfig createConfig(int millSec){
        //配置连接超时时间
        if (millSec != 0){
            return  RequestConfig.custom()
                    .setConnectTimeout(millSec)
                    .setConnectionRequestTimeout(millSec)
                    .setSocketTimeout(60000)
                    .setRedirectsEnabled(true)
                    .build();
        }else{
            return  RequestConfig.custom()
                    .setConnectTimeout(3000)
                    .setConnectionRequestTimeout(3000)
                    .setSocketTimeout(60000)
                    .setRedirectsEnabled(true)
                    .build();
        }
    }
}
